﻿using System;
using System.Net;
using System.Windows;

using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;

namespace Coding4Fun.UsbCannon.Phone
{
	public partial class MainPage : PhoneApplicationPage
	{
		bool _isPortrait;
		string _endPointServer = "crutkasdesktop";
		public AppSettings ApplicationSettings;

		// Constructor
		public MainPage()
		{
			InitializeComponent();
		}

		private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
		{
            VisualStateManager.GoToState(this, "Start", false);
            VisualStateManager.GoToState(this, "Normal", true);

			DataContext = this;
			
			SetIsPortaitMode();
			SetAppSettings();

			var sensor = new Accelerometer();
			sensor.ReadingChanged += sensor_ReadingChanged;
			sensor.Start();
		}

		private void SetAppSettings()
		{
			if(ApplicationSettings == null)
				ApplicationSettings = AppSettings.Load();

			_endPointServer = ApplicationSettings.EndpointUrl;
		}

		private void SetIsPortaitMode()
		{
			_isPortrait = Orientation == PageOrientation.PortraitUp || Orientation == PageOrientation.PortraitDown;
		}

		private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
		{
			SetIsPortaitMode();
		}

		void sensor_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
		{
            var top = (_isPortrait) ? e.Y : e.X;
            var side = (_isPortrait) ? e.X : e.Y;

			double pitch, roll;
			CalculatePitchAndRoll(top, side, e.Z, out pitch, out roll);

			sendHttpCommand(pitch, roll);
			
			Dispatcher.BeginInvoke(() =>
			{
				PitchAngle = pitch;
				RollAngle = roll;

			});
		}

		private static void CalculatePitchAndRoll(double top, double side, double through, out double pitch, out double roll)
		{
			pitch = CalculateAngle(side, top);
			roll = CalculateAngle(top, through);

			if (top < 0)
			{
				// left side Y is positive
				pitch += (side > 0) ? -180 : 180;
				roll *= -1;
			}

			roll -= 90;
		}

		private static double CalculateAngle(double y, double x)
		{
			if (y != 0 && x != 0)
				return Math.Atan2(y, x) * 180 / Math.PI;

			return 0;
		}

		public double PitchAngle
		{
			get { return (double)GetValue(PitchAngleProperty); }
			set { SetValue(PitchAngleProperty, value); }
		}

		// Using a DependencyProperty as the backing store for PitchAngle.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PitchAngleProperty =
			DependencyProperty.Register("PitchAngle", typeof(double), typeof(MainPage), new PropertyMetadata(0.0));

		public double RollAngle
		{
			get { return (double)GetValue(RollAngleProperty); }
			set { SetValue(RollAngleProperty, value); }
		}

		// Using a DependencyProperty as the backing store for PitchAngle.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty RollAngleProperty =
			DependencyProperty.Register("RollAngle", typeof(double), typeof(MainPage), new PropertyMetadata(0.0));

		private void ExecuteCommand(string command)
		{
			var requestUriString = string.Format("http://{0}:31337/?command={1}", _endPointServer, command.ToLower());

			var request = (HttpWebRequest)WebRequest.Create(requestUriString);
			request.Method = "GET";
			request.BeginGetResponse(ExecuteCommandCallback, null);
		}

		static void ExecuteCommandCallback(IAsyncResult result) { }

		private void UXSettingsButton_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			var settings = new Settings(ApplicationSettings);

			settings.Finished += settings_Finished;
			LayoutRoot.Children.Add(settings);
		}

		void settings_Finished(object sender, EventArgs e)
		{
			LayoutRoot.Children.RemoveAt(LayoutRoot.Children.Count - 1);
			SetAppSettings();
		}

		private void Button_Click(object sender, RoutedEventArgs e)
		{
			UXSB_Alarm.Begin();
			lastCommand = "fire";
			ExecuteCommand(lastCommand);
		}

		int counter;
		string lastCommand;
		private void sendHttpCommand(double pitch, double roll)
		{
			if (counter < 5)
			{
				counter++;
				return;
			}

			counter = 0;
			var command = "Off";

			if (roll > 75)
			{
				command = "Down";
			}
			else if (roll < 20)
			{
				command = "Up";
			}

			if (pitch > 40)
			{
				command = "Left";
			}
			else if (pitch < -40)
			{
				command = "Right";
			}

			if (lastCommand == command)
				return;

			Dispatcher.BeginInvoke(()=> VisualStateManager.GoToState(this, command, true)); 

			ExecuteCommand(command);
			lastCommand = command;
		}
	}
}
